package cn.catsdad.base.processor;

import cn.catsdad.base.entity.BaseEntity;
import cn.catsdad.base.page.PageBean;
import cn.catsdad.base.page.PageParam;
import cn.catsdad.cache.factory.ICacheRepository;
import cn.catsdad.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xuyl
 * @version 1.0 2024/7/14
 */
@Component
public class CacheProcessor<T extends BaseEntity> implements IBaseServiceProcessor<T, Long> {

    private ICacheRepository cacheRepository;

    @Override
    public int getOrder() {
        return 0;
    }

    private String getRedisKey(Collection<T> entities) {
        List<T> list = new ArrayList<>(entities);
        T t = list.get(0);
        String name = t.getClass().getName();
        return name.replace(".", ":");
    }

    @Override
    public void preSave(Collection<T> entities) {

    }

    @Override
    public void preInsert(Collection<T> entities) {

    }

    @Override
    public void preUpdate(Collection<T> entities) {

    }

    @Override
    public void preDelete(Collection<Long> longs) {

    }

    @Override
    public void preEntityDeleted(Collection<T> entities) {

    }

    @Override
    public List<T> preQuery(Collection<Long> longs, Class<T> clazz) {
        if (StringUtil.isNotEmpty(longs) && clazz != null) {
            String redisKey = clazz.getName().replace(".", ":");
            List<String> keys = new ArrayList<>(longs.size());
            for (Long aLong : longs) {
                keys.add(aLong.toString());
            }
            return cacheRepository.multiGetMapCacheObject(redisKey, keys);
        }
        return new ArrayList<>();
    }

    @Override
    public void prePageQuery(PageBean<T> pageBean, PageParam pageParam) {

    }

    @Override
    public void postSave(Collection<T> entities) {
        saveCache(entities);
    }

    @Override
    public void postInsert(Collection<T> entities) {
        saveCache(entities);
    }

    @Override
    public void postUpdate(Collection<T> entities) {
        saveCache(entities);
    }

    @Override
    public void postDelete(Collection<Long> keys, Class<T> clazz) {
        if (StringUtil.isNotEmpty(keys) && clazz != null) {
            String redisKey = clazz.getName().replace(".", ":");
            List<String> mapKeys = new ArrayList<>(keys.size());
            keys.forEach(k -> mapKeys.add(k.toString()));
            cacheRepository.deleteMapValue(redisKey, mapKeys);
        }
    }

    @Override
    public void postEntityDelete(Collection<T> entities) {
        if (StringUtil.isNotEmpty(entities)) {
            String redisKey = getRedisKey(entities);
            List<String> mapKeys = entities.stream().map(t -> t.getId().toString()).collect(Collectors.toList());
            cacheRepository.deleteMapValue(redisKey, mapKeys);
        }
    }

    @Override
    public void postQuery(Collection<T> entities) {

    }

    @Override
    public void postPageQuery(PageBean<T> pageBean, PageParam pageParam) {

    }

    /**
     * 保存实体到缓存
     *
     * @param entities 实体对象
     */
    private void saveCache(Collection<T> entities) {
        if (StringUtil.isNotEmpty(entities)) {
            String redisKey = getRedisKey(entities);
            Map<String, Object> cacheMap = new HashMap<>();
            entities.forEach(e -> cacheMap.put(e.getId().toString(), e));
            cacheRepository.putAllMapValue(redisKey, cacheMap);
        }
    }

    @Autowired
    @Lazy
    public void setCacheRepository(ICacheRepository cacheRepository) {
        this.cacheRepository = cacheRepository;
    }
}
